package com.inner;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.binary.Hex;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * 参考《银联商务内部接口规范V0.7》
 * @author wuwenzhe
 *
 */
public class PackAndUnpackDemo {
	private static final String PUB_KEY="30819f300d06092a864886f70d010101050003818d00308189028181008175f4290466f25d0a95984ddc173bf671913b52ea1c7093631aecdb9cdd378426806d3f98b3c72fd8468f217c16b0b9629ec41ee766ab05ee6661425271d97df85c81e026e7f4b2f784917c0f2223829392d59ecae232682aa98fd34f4c34d44c7b7cea132d3da838f72e798c5fc94ab9d442948677695e8b5c129e35e323ad0203010001";
	private static final String PRI_KEY="30820276020100300d06092a864886f70d0101010500048202603082025c020100028181008175f4290466f25d0a95984ddc173bf671913b52ea1c7093631aecdb9cdd378426806d3f98b3c72fd8468f217c16b0b9629ec41ee766ab05ee6661425271d97df85c81e026e7f4b2f784917c0f2223829392d59ecae232682aa98fd34f4c34d44c7b7cea132d3da838f72e798c5fc94ab9d442948677695e8b5c129e35e323ad020301000102818050e0cee39d236f809eef2c52601087de83beb6b02b200f5894ceaa70dd03fafded4bc874b5c282cb2a339291d9c3172f0a24a3e3a6af26633337f4c5095aa503c102b67baf61b886721867e9246348a689e93e70f7490fac360daab8dc8e23a87a9d3881957ca31a83b5ccf1638af6992693a5e84e84535f405a770d0caa03c5024100c0b4c8011cf5455a083f04888d1dbb4bea5e9e5f717855ad4e70b950937d461362831cd54a01f5faabe4bf57e580dc873e8c89badfa587fe44aab29685c4cacb024100abfb56c3df471a10ce9d84b0272edfdd4201994e3b6ea21a986ea162a4c148296ca38a132901e8bcd2314629cbc247e4fb5c0d6f82dd0c571e28b8dd1a732467024055df3950e5aa9660ec53c89d60e4e2d58d76e473fb8878056672ece16f17dfe63b7bd999620545ab9275b89e5e72f1d28298f5b7047a2b03af6db16f49e4cbc9024060558b46707d3d6688b5c72b7ce74ed27b34b611124d6854096a7ecfe885b3cc306472e544a5231f1186344d192b9c65f13ea0f003979a5ffa2ec94e60907aa5024100b00681e2c60e1aad79c691aadec72a47bcd89b677a8df7c10eff4445647e7d4890ea73a11451fe97d9f3d9dd3626ea3b31fd5593757b3f1f9fd478775097be47";
	private static String HEAD_SEPARATOR = "\"";
	private static String TAIL_SEPARATOR = ",\"MsgMac\":";
	
	public static void main(String[] args) throws Exception{
		Map<String,String> body=new HashMap<String,String>();
		body.put("userNo", "370203");
		body.put("acctNo", "4349100110489705");
		body.put("acctName", "姜志军");
		body.put("certNo", "339005198203045421");
		body.put("certType", "00");
		body.put("phone", "18321058884");
		
		String msg=getRequestMsg(body,PRI_KEY,"10009","00005","实名验证");
		System.out.println(msg);
		boolean result=verify(msg,PUB_KEY);
		System.out.println("验签结果:"+result);
	}
	
    public static String getRequestMsg(Map<String,String> body,String priKey,String channelId,String transId,String transName) throws Exception{
		OutputMessageProto requestMsg=new OutputMessageProto();
		MsgHeadProto head=new MsgHeadProto();

		requestMsg.setMsgHead(head);
		requestMsg.setMsgBody(body);
		
		head.setCharSet(MsgHeadProto.CHARSET_UTF8);
		head.setEncryptCertId("123456789");
		head.setMsgNum(MsgHeadProto.MSG_TOTAL_NUM);
		head.setMsgTotalNum(MsgHeadProto.MSG_TOTAL_NUM);
		//对应channelID标志调用者身份
		head.setOrgSenderID(channelId);
		head.setOrgReceiverID("0000000004");
		
//		head.setOrgReceiverID("00000004");
		head.setOrgSendDate("20161012");
		head.setOrgSendTime("110454");
		head.setOrgSendTransID("20170322142315221");
		//serviceID，标志所请求的服务
		head.setTransID(transId);
		head.setTransName(transName);
		head.setTransParentFlag(MsgHeadProto.TRANSPARENT_FLAG_DONOT_GET_THROUGH);
		head.setTransParentType(MsgHeadProto.TRANSPARENT_TYPE_NONE);
		head.setTransType(MsgHeadProto.TRANS_TYPE_INFO);
		head.setVersionID(MsgHeadProto.VERSION_ID);
		head.setType(MsgHeadProto.TYPE_REQUEST);
		
		String messageStr = JSON.toJSONString(requestMsg);
		byte[] messageBytes = messageStr.getBytes("UTF-8");
		
		byte[] priKeyBytes=null;
		try {
			priKeyBytes = Hex.decodeHex(priKey.toCharArray());
		} catch (Exception e) {
			throw new RuntimeException("私钥格式错误，bad format privateKey",e);
		}
		byte[] signature = SignatureUtils.sign(messageBytes, priKeyBytes);

		// 产生MsgMac部分
		String signatureStr=Hex.encodeHexString(signature);
		MsgMacProto mac=new MsgMacProto();
		requestMsg.setMsgMac(mac);
		mac.setSignature(signatureStr);
		// 返回打包结果
		String requestStr = JSON.toJSONString(requestMsg);
		return requestStr;
    }
    
    /**
     * 验证签名
     * @return
     * @throws Exception 
     */
    public static boolean verify(String requestStr,String pubKey) throws Exception{
    	OutputMessageProto msg=JSONObject.parseObject(requestStr, OutputMessageProto.class);
    	String sign=msg.getMsgMac().getSignature();
    	byte[] sigBytes = Hex.decodeHex(sign.toCharArray());
    	
		int beginIndex = requestStr.indexOf(HEAD_SEPARATOR);
		int endIndex = requestStr.lastIndexOf(TAIL_SEPARATOR);
		String message = requestStr.substring(beginIndex, endIndex);
		String messageWithBracket="{"+message+"}";
		byte[] messageBytes = messageWithBracket.getBytes("UTF-8");
		
		byte[] pubKeyBytes=Hex.decodeHex(pubKey.toCharArray());
		
		boolean verifyResult = SignatureUtils.verify(messageBytes,
				pubKeyBytes, sigBytes);
		return verifyResult;
    }
    
}
